/**
 * HTTP客户端配置
 * 用于统一处理API请求，包括身份验证和错误处理
 */

// 获取存储的令牌
export const getAuthToken = (): string | null => {
  if (typeof window === 'undefined') return null;
  return localStorage.getItem('token');
};

// 添加身份验证头部
export const getAuthHeaders = (): Record<string, string> => {
  const token = getAuthToken();
  if (!token) return {};
  return {
    Authorization: `Bearer ${token}`,
  };
};

// API请求函数
export async function apiRequest<T>(
  url: string,
  options: RequestInit = {}
): Promise<T> {
  // 合并默认选项和传入的选项
  const defaultOptions: RequestInit = {
    headers: {
      'Content-Type': 'application/json',
      ...getAuthHeaders(),
      ...(options.headers || {}),
    },
  };

  const mergedOptions = {
    ...defaultOptions,
    ...options,
  };

  // 发送请求
  const response = await fetch(url, mergedOptions);

  // 处理响应
  if (!response.ok) {
    // 如果收到401错误，清除令牌
    if (response.status === 401) {
      if (typeof window !== 'undefined') {
        localStorage.removeItem('token');
        localStorage.removeItem('user');
        // 如果不是登录页面，则重定向到登录页面
        if (!window.location.pathname.includes('/login')) {
          window.location.href = `/login?callbackUrl=${encodeURIComponent(window.location.pathname)}`;
        }
      }
    }

    // 尝试解析错误响应
    try {
      const errorData = await response.json();
      throw new Error(errorData.error || `请求失败: ${response.status}`);
    } catch (e) {
      if (e instanceof Error) throw e;
      throw new Error(`请求失败: ${response.status}`);
    }
  }

  // 如果是204 No Content，返回null
  if (response.status === 204) {
    return null as unknown as T;
  }

  // 解析JSON响应
  return await response.json();
}

// 快捷方法
export const http = {
  get: <T>(url: string, options?: RequestInit) => 
    apiRequest<T>(url, { ...options, method: 'GET' }),
  
  post: <T>(url: string, data?: any, options?: RequestInit) => 
    apiRequest<T>(url, { 
      ...options, 
      method: 'POST',
      body: data ? JSON.stringify(data) : undefined,
    }),
  
  put: <T>(url: string, data?: any, options?: RequestInit) => 
    apiRequest<T>(url, { 
      ...options, 
      method: 'PUT',
      body: data ? JSON.stringify(data) : undefined,
    }),
  
  delete: <T>(url: string, options?: RequestInit) => 
    apiRequest<T>(url, { ...options, method: 'DELETE' }),
}; 